﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DnPakExplorer.Forms {
	public partial class FormBase : Form {

		private Pen mBorderPen = new Pen(Color.FromArgb(16, 16, 16), 1);
		private static Image[] mCloseButtomStateImage = new Image[]{
			Properties.Resources.close_normal, Properties.Resources.close_highlight, Properties.Resources.close_press
		};

		private static Image[] mMaxButtonStateImage = new Image[]{
			Properties.Resources.max_normal, Properties.Resources.max_highlight, Properties.Resources.max_press,
			Properties.Resources.restore_normal, Properties.Resources.restore_highlight, Properties.Resources.restore_press,
		};

		private static Image[] mMinButtonStateImage = new Image[]{
			Properties.Resources.min_normal, Properties.Resources.min_highlight, Properties.Resources.min_press
		};

		private int mSystemButtonMarginTop = 3;
		private int mSystemButtonMarginRight = 3;
		private int mSystemButtonMargin = 2;

		[Browsable(true)]
		public Color BorderColor {
			get { return mBorderPen.Color; }
			set { mBorderPen.Color = value; }
		}

		[Browsable(true)]
		public int SystemButtonMarginTop {
			get { return mSystemButtonMarginTop; }
			set { 
				mSystemButtonMarginTop = value;
				UpdateSysButtons();
			}
		}

		[Browsable(true)]
		public int SystemButtonMarginRight {
			get { return mSystemButtonMarginRight; }
			set { 
				mSystemButtonMarginRight = value;
				UpdateSysButtons();
			}
		}

		[Browsable(true)]
		public int SystemButtonMargion {
			get { return mSystemButtonMargin; }
			set {
				mSystemButtonMargin = value;
				UpdateSysButtons();
			}
		}


		[StructLayout(LayoutKind.Sequential)]
		public struct MARGINS {
			public int Left;
			public int Right;
			public int Top;
			public int Bottom;
		}

		[DllImport("dwmapi.dll", PreserveSig = false)]
		static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

		[DllImport("dwmapi.dll", PreserveSig = false)]
		static extern bool DwmIsCompositionEnabled(); //Dll 导入 DwmApi

		protected override void OnLoad(EventArgs e) {
			//如果启用Aero
			if (DwmIsCompositionEnabled() && !DesignMode) {
				MARGINS m = new MARGINS();
				m.Left = m.Top = m.Right = m.Bottom = 1;
				DwmExtendFrameIntoClientArea(this.Handle, ref m); //开启全窗体透明效果
			}
			base.OnLoad(e);

		}

		protected override void OnFormClosing(FormClosingEventArgs e) {
			base.OnFormClosing(e);
		}

		public FormBase() {
			InitializeComponent();
			SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.ResizeRedraw, true);
			closeButton.NormalBackImage = mCloseButtomStateImage[0];
			closeButton.HoveredBackImage = mCloseButtomStateImage[1];
			closeButton.PressedBackImage = mCloseButtomStateImage[2];
			minButton.NormalBackImage = mMinButtonStateImage[0];
			minButton.HoveredBackImage = mMinButtonStateImage[1];
			minButton.PressedBackImage = mMinButtonStateImage[2];
			this.Shown += FormBase_Shown;
		}

		void FormBase_Shown(object sender, EventArgs e) {
			//WindowsUtil.SetFormRoundRectRgn(this, 5);
		}


		protected override CreateParams CreateParams {
			get {
				CreateParams cp = base.CreateParams;
				if (!DesignMode) {
					if (MaximizeBox) {
						cp.Style |= (int)WindowStyle.WS_MAXIMIZEBOX;
					}
					if (MinimizeBox) {
						cp.Style |= (int)WindowStyle.WS_MINIMIZEBOX;
					}
					cp.Style |= (int)WindowStyle.WS_SIZEBOX;
					//cp.Style |= (int)(WindowStyle.WS_CAPTION); // 添加标题会有最小和最大化动画
					cp.ExStyle |= (int)WindowStyle.WS_CLIPCHILDREN;  //防止因窗体控件太多出现闪烁
					cp.ClassStyle |= (int)ClassStyle.CS_DropSHADOW;  //实现窗体边框阴影效果
				}
				//cp.Style = unchecked((int)0x960f0000);
				return cp;
			}
		}

		protected override void OnPaint(PaintEventArgs e) {
			base.OnPaint(e);
		}

		protected override void OnPaintBackground(PaintEventArgs e) {
			base.OnPaintBackground(e);
			//if (DwmIsCompositionEnabled()) {
			//	e.Graphics.Clear(Color.Black); //将窗体用黑色填充（Dwm 会把黑色视为透明区域）
			//}
			e.Graphics.DrawRectangle(mBorderPen, 0, 0, Width-1, Height-1);
		}

		protected override void OnSizeChanged(EventArgs e) {
			base.OnSizeChanged(e);
			//WindowsUtil.SetFormRoundRectRgn(this, 5);
			UpdateSysButtons();
		}


		protected override void WndProc(ref Message m) {
			switch (m.Msg) {
			case Win32.WM_NCHITTEST:
				WmNcHitTest(ref m);
				break;
			case Win32.WM_NCPAINT:
				//Graphics g=Graphics.FromHwndInternal(m.HWnd);
				//g.DrawRectangle(mBorderPen, 0, 0, Width-1, Height-1);
				//g.Dispose();
				break;
			case Win32.WM_NCCALCSIZE:
				if (m.WParam == (IntPtr)Win32.WM_TRUE) {
					NCCalcSize_Params param = (NCCalcSize_Params)Marshal.PtrToStructure(m.LParam, typeof(NCCalcSize_Params));
					//m.Result = IntPtr.Zero;
					param.rect1.left -= 1;
					param.rect1.top -= 1;
					param.rect1.right -= 1;
					param.rect1.bottom -= 1;
				} else {
				}
				break;
			case Win32.WM_NCACTIVATE:
				if (m.WParam == (IntPtr)Win32.WM_FALSE)
					m.Result = (IntPtr)Win32.WM_TRUE;
				break;
			//case Win32.WM_ERASEBKGND:
			//	m.Result = IntPtr.Zero;
			//	break;
			default:
				base.WndProc(ref m);
				break;
			}

		}




		protected override void OnMouseDown(MouseEventArgs e) {
			base.OnMouseDown(e);
			if (e.Button == MouseButtons.Left) {
				WindowsUtil.MoveWindow(this);
			}
		}

		private void label1_MouseDown(object sender, MouseEventArgs e) {
			if (e.Button == MouseButtons.Left) {
				WindowsUtil.MoveWindow(this);
			}
		}

		private void UpdateSysButtons() {
			maxButton.NormalBackImage = mMaxButtonStateImage[WindowState==FormWindowState.Maximized?3:0];
			maxButton.HoveredBackImage = mMaxButtonStateImage[WindowState==FormWindowState.Maximized?4:1];
			maxButton.PressedBackImage = mMaxButtonStateImage[WindowState==FormWindowState.Maximized?5:2];
			int right = Width;
			right -= closeButton.Width + SystemButtonMarginRight;
			closeButton.Location = new Point(right, SystemButtonMarginTop);
			right -= maxButton.Width + SystemButtonMargion;
			maxButton.Location = new Point(right, SystemButtonMarginTop);
			right -= minButton.Width + SystemButtonMargion;
			minButton.Location = new Point(right, SystemButtonMarginTop);
		}

		//调整窗体大小
		private void WmNcHitTest(ref Message m) {
			int wparam = m.LParam.ToInt32();
			Point mouseLocation = new Point(WindowsUtil.LOWORD(wparam), WindowsUtil.HIWORD(wparam));
			mouseLocation = PointToClient(mouseLocation);

			if (WindowState != FormWindowState.Maximized) {
				if (true) {
					if (mouseLocation.X < 5 && mouseLocation.Y < 5) {
						m.Result = new IntPtr(Win32.HTTOPLEFT);
						return;
					}

					if (mouseLocation.X > Width - 5 && mouseLocation.Y < 5) {
						m.Result = new IntPtr(Win32.HTTOPRIGHT);
						return;
					}

					if (mouseLocation.X < 5 && mouseLocation.Y > Height - 5) {
						m.Result = new IntPtr(Win32.HTBOTTOMLEFT);
						return;
					}

					if (mouseLocation.X > Width - 5 && mouseLocation.Y > Height - 5) {
						m.Result = new IntPtr(Win32.HTBOTTOMRIGHT);
						return;
					}

					if (mouseLocation.Y < 3) {
						m.Result = new IntPtr(Win32.HTTOP);
						return;
					}

					if (mouseLocation.Y > Height - 3) {
						m.Result = new IntPtr(Win32.HTBOTTOM);
						return;
					}

					if (mouseLocation.X < 3) {
						m.Result = new IntPtr(Win32.HTLEFT);
						return;
					}

					if (mouseLocation.X > Width - 3) {
						m.Result = new IntPtr(Win32.HTRIGHT);
						return;
					}
				}
			}
			m.Result = new IntPtr(Win32.HTCAPTION);
		}

		protected virtual void OnCloseButton(object sender, EventArgs e) {
			Close();
		}

		private void OnMaxButton(object sender, EventArgs e) {
			WindowState = WindowState != FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal;
		}

		private void OnMinButton(object sender, EventArgs e) {
			WindowState = WindowState != FormWindowState.Minimized ? FormWindowState.Minimized : FormWindowState.Normal;
		}

		private void FormBase_TextChanged(object sender, EventArgs e) {
			title.Text = Text;
		}

	}
}
